﻿using System;
using fastCSharp;
using System.Threading;

namespace diantou.web.management
{
    /// <summary>
    /// 数据库表格
    /// </summary>
    [fastCSharp.code.cSharp.webView(IsPage = false, IsPool = true)]
    partial class sqlTable : adminView<sqlTable>
    {
        /// <summary>
        /// 数据源类型
        /// </summary>
        internal enum type : byte
        {
            /// <summary>
            /// 默认数据
            /// </summary>
            Data,
            /// <summary>
            /// 考试数据
            /// </summary>
            Exam
        }
        /// <summary>
        /// 数据库表格
        /// </summary>
        private struct table
        {
            /// <summary>
            /// 名称
            /// </summary>
            public string Name;
            /// <summary>
            /// 类型全名
            /// </summary>
            public string FullName;
            /// <summary>
            /// 数据源类型
            /// </summary>
            public type Type;
        }
        /// <summary>
        /// 数据库表格集合
        /// </summary>
        private static table[] allTables = nullValue<table>.Array;
        /// <summary>
        /// 数据库表格集合访问锁
        /// </summary>
        private static readonly object tableLock = new object();
        /// <summary>
        /// 是否加载完数据库表格集合
        /// </summary>
        private static bool isTable;
        /// <summary>
        /// 是否加载完数据库表格集合
        /// </summary>
        private static bool[] isTables = new bool[fastCSharp.Enum.GetMaxValue<type>(-1) + 1];
        /// <summary>
        /// 获取数据库表格集合
        /// </summary>
        /// <returns></returns>
        private static table[] getTables()
        {
            if (!isTable)
            {
                Monitor.Enter(tableLock);
                try
                {
                    if (!isTable)
                    {
                        subArray<table> tableArray = new  subArray<table>(allTables);
                        load(type.Data, diantou.dataAccess.tcpCall.sqlTableJsonTool.getNames, ref tableArray);
                        load(type.Exam, diantou.examDataAccess.tcpCall.sqlTableJsonTool.getNames, ref tableArray);
                        table[] newTables = tableArray.ToArray();
                        int index = 0;
                        foreach (table table in newTables)
                        {
                            if (table.Name == null) newTables[index++].Name = table.FullName.Substring(table.FullName.LastIndexOf('.') + 1);
                        }
                        allTables = newTables.sort((left, right) => string.CompareOrdinal(left.Name, right.Name));
                    }
                }
                finally { Monitor.Exit(tableLock); }
            }
            return allTables;
        }
        /// <summary>
        /// 获取数据库表格集合
        /// </summary>
        /// <param name="type"></param>
        /// <param name="getNames"></param>
        /// <param name="newTables"></param>
        private static void load(type type, Func<fastCSharp.net.returnValue<string[]>> getNames, ref subArray<table> newTables)
        {
            if (!isTables[(byte)type])
            {
                fastCSharp.net.returnValue<string[]> names = getNames();
                if (names.Type == fastCSharp.net.returnValue.type.Success)
                {
                    foreach (string name in names.Value) newTables.Add(new table { FullName = name, Type = type });
                }
                isTables[(byte)type] = true;
            }
        }

        /// <summary>
        /// 数据库表格类型名称集合
        /// </summary>
        private table[] tables { get { return getTables(); } }
        /// <summary>
        /// 自增字段名称
        /// </summary>
        private string identity;
        /// <summary>
        /// 关键字名称集合
        /// </summary>
        private string[] primaryKeys;
        /// <summary>
        /// 是否自增模式
        /// </summary>
        private bool isIdentity
        {
            get { return true; }
        }
    }
}
